using Digitalmes.Application.Scada.Commands;
using Digitalmes.Domain;
using Digitalmes.Domain.Enums;
using Digitalmes.Infrastructure.Scada.Extensions;
using ThingsEdge.Exchange.Contracts;

namespace Digitalmes.Infrastructure.Scada.Handlers;

/// <summary>
/// 设备点检处理。
/// </summary>
internal sealed class EquipmentInspectHandler(ISender sender, ILogger<EquipmentInspectHandler> logger) : IScadaAskHandler
{
    public async Task<ScadaResult> HandleAsync(RequestMessage message, CancellationToken cancellationToken = default)
    {
        var partNo = message.GetString(TagDefinition.PLC_Inspect_PartNo);

        // 请求日志
        logger.LogInformation("[设备点检请求数据] 产线：{LineName}，工位：{WsCode}，标件：{PartNo}, 数据：{Message}",
            message.Schema.ChannelName,
            message.Schema.TagGroupName,
            partNo ?? "-",
            message.Values.Select(s => new { s.TagName, s.Address, s.Value }).ToJson());

        // 工步过点结果可以不设定
        int? passResult = message.GetData(TagDefinition.PLC_Inspect_PassResult)?.GetInt();
        if (passResult.HasValue && !Enum.IsDefined(typeof(PassEnum), passResult.Value))
        {
            return LoggerHelper.LogAndReturn(logger, "设备点检响应", message.Schema.ChannelName, message.Schema.TagGroupName!, ErrorCode.E1701);
        }

        EquipmentInspectCommand command = new()
        {
            LineCode = message.Schema.ChannelName,
            WsCode = message.Schema.TagGroupName,
            Alias = message.Self().GetExtraValue("Alias"), // 别名
            PartNo = partNo,
            PassResult = passResult.HasValue ? (PassEnum)passResult.Value : default,
            DataList = message.Values,
        };

        try
        {
            var result = await sender.Send(command, cancellationToken).ConfigureAwait(false);

            // 响应日志
            logger.LogInformation("[设备点检响应] 产线：{LineName}，工位：{WsCode}，状态: {State}, 消息: [{InnerErrorCode}]-{ErrMessage}; 回调值: {CallbackItems}",
                message.Schema.ChannelName,
                message.Schema.TagGroupName,
                result.State.ToString(),
                result.InnerErrorCode.ToString(),
                result.GetErrorMessage(),
                result.CallbackItems.ToJson() ?? "[]");

            return result;
        }
        catch (Exception ex)
        {
            logger.LogError(ex, "[设备点检服务处理异常] 产线：{LineName}，工位：{WsCode}",
                message.Schema.ChannelName,
                message.Schema.TagGroupName);
            return ScadaResult.Error();
        }
    }
}
